package com.cn.fw4j.util;

import groovy.lang.GroovyClassLoader;
import groovy.lang.GroovyClassLoader.InnerLoader;
import groovy.lang.GroovyObject;

import java.io.File;
import java.io.IOException;
import java.util.LinkedHashMap;
import java.util.Map;

import org.codehaus.groovy.control.CompilationFailedException;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

/**
 * Groovy 加载工具
 * @author user
 *
 */
public final class GroovyLoaderHelper {
	private static Logger logger = LoggerFactory.getLogger(GroovyLoaderHelper.class);
	private final static GroovyLoaderHelper instance = new GroovyLoaderHelper();
	/**
	 * 类加载器
	 */
	private ClassLoader parentLoader = Thread.currentThread().getContextClassLoader();
	/**
	 * Groovy 文件池
	 * key : 文件名
	 * value : 文件路径
	 */
	private Map<String,File> groovyPool = new LinkedHashMap<String,File>();
	
	private GroovyLoaderHelper(){}
	
	public final static GroovyLoaderHelper getInstance(){
		return instance;
	}
	/**
	 * 添加Groovy路径
	 * @param name 文件名
	 * @param path 路径
	 */
	public synchronized void putGroovyPath(String name,String path) {
		if(!this.groovyPool.containsKey(name)){
			logger.info(path);
			this.groovyPool.put(name, new File(path));
			return;
		}
		logger.error("class "+name+" 以存在");
	}
	/**
	 * 获取 Groovy 实例
	 * @param name
	 * @return GroovyObject
	 * @throws CompilationFailedException
	 * @throws IOException
	 * @throws InstantiationException
	 * @throws IllegalAccessException
	 */
	public synchronized GroovyObject getGroovyInstance(String name) 
			throws CompilationFailedException, IOException, InstantiationException, IllegalAccessException{
		GroovyClassLoader gl = new GroovyClassLoader(this.parentLoader);
		InnerLoader il = new InnerLoader(gl);
		for(String key : this.groovyPool.keySet()){
			logger.debug("loading "+key);
			il.parseClass(this.groovyPool.get(key));
		}
		Class<?> obj = il.parseClass(this.groovyPool.get(name));
		il.close();
		return (GroovyObject)obj.newInstance();
	}
	/**
	 * 获取 Groovy Class
	 * @param name
	 * @return Class<?>
	 * @throws CompilationFailedException
	 * @throws IOException
	 */
	public synchronized Class<?> getGroovyClass(String name)
			throws CompilationFailedException, IOException{
		GroovyClassLoader gl = new GroovyClassLoader(this.parentLoader);
		InnerLoader il = new InnerLoader(gl);
		for(String key : this.groovyPool.keySet()){
			logger.debug("loading "+key);
			il.parseClass(this.groovyPool.get(key));
		}
		Class<?> ret = il.parseClass(this.groovyPool.get(name));
		il.close();
		return ret;
	}
}
